﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil;

namespace CILADA.Engine
{
    public class DynamicDependency : AssemblyReference, IComparable
    {
        public TypeReference Type { get; private set; }
        public MethodReference Method { get; private set; }
        public string DependencyName { get; private set; }

        public DynamicDependency(TypeReference type, MethodReference method, string dependencyName)
        {
            this.Type = type;
            this.Method = method;
            this.DependencyName = dependencyName;
        }

        public override bool Equals(object obj)
        {
            if (obj is DynamicDependency)
            {
                DynamicDependency other = obj as DynamicDependency;
                if (other == null) return false;

                bool sameType = this.Type.Equals(other.Type.FullName);
                bool sameMethod = this.Method.ToString().Equals(other.Method.ToString());
                bool sameName = this.DependencyName.Equals(other.DependencyName);

                return (sameType && sameMethod && sameName);
            }
            else
            {
                return false;
            }
        }

        public override int GetHashCode()
        {
            // this is bad, can give same hash code for two dif objects
            return this.DependencyName.GetHashCode() + this.Method.GetHashCode() + this.Type.GetHashCode();
        }

        public override string ToString()
        {
            return this.Type.FullName + "::" + this.Method.Name + " may create a dynamic dependency with " + this.DependencyName;
        }

        #region IComparable Members

        public override int CompareTo(object obj)
        {
            DynamicDependency other = (DynamicDependency)obj;

            if (this.From != null)
            {
                int compFrom = this.From.CompareTo(other.From);
                if (compFrom != 0)
                {
                    return compFrom;
                }
            }

            if (this.To != null)
            {
                int compTo = this.To.CompareTo(other.To);
                if (compTo != 0)
                {
                    return compTo;
                }
            }

            if (this.DependencyName != null)
            {
                int compDepName = this.DependencyName.CompareTo(other.DependencyName);
                if (compDepName != 0)
                {
                    return compDepName;
                }
            }

            if (this.Type != null)
            {
                int compType = this.Type.FullName.CompareTo(other.Type.FullName);
                if (compType != 0)
                {
                    return compType;
                }
            }

            if (this.Method != null)
            {
                int compMethod = this.Method.Name.CompareTo(other.Method.Name);
                if (compMethod != 0)
                {
                    return compMethod;
                }
            }

            return 0;
        }

        #endregion
    }
}
